﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using System.Globalization;
using GrupyzServices.Logging;
using Webdiyer.WebControls.Mvc;
using System.Web;
using System.Data.Objects;

namespace GrupyzServices.BdAccess
{
    public class DealRepository : IDealRepository
    {
        GrupyzEntities _entity;
        ILogger log;

        public DealRepository()
        {
            _entity = new GrupyzEntities();
            log = new NLogLogger();
        }

        public IEnumerable<Deal> GetDeals()
        {
            return from x in _entity.Deal.Include("Artigo").Include("Localidade.Zona")
                   where x.Disponivel == true 
                   select x;
        }

        public Deal GetDeal(int id)
        {
            return (from x in _entity.Deal.Include("Artigo").Include("Detalhe")
                    where x.Disponivel == true 
                    && x.Id == id
                    select x).SingleOrDefault();
        }

        public DealViewModel GetDayDeal()
        {

            var deal =  (from x in _entity.Deal.Include("Artigo").Include("Detalhe")
                        where x.Disponivel == true  
                        && x.DayDeal == true
                        select x).SingleOrDefault();

            return ReturnDealViewModel(deal);

        }

        public IEnumerable<QtdVendida> GetQtdVendida(int id)
        {
            return from x in _entity.Deal
                    where x.Id == id
                   select new QtdVendida{
                    QtdVend = x.TotalComprado,
                    Disponivel = x.QuantidadeMaxima <= x.TotalComprado ? false : true,
                    IdDeal = x.Id,
                    DealOn = x.QuantidadeMinima <= x.TotalComprado ? true : false,
                    }; 
        }


        public IEnumerable<Deal> GetDayDeals()
        {
            return from x in _entity.Deal.Include("Artigo").Include("Localidade.Zona")
                   where x.Disponivel == true
                   && x.DayDeal == true
                   select x;
        }


        public bool VerificaDeal(int id, string nome)
        {
            try
            {
                if (GetDeal(id) == null) return false;
                if (GetDealByNome(nome) == null) return false;
                return true;
            }
            catch (Exception ex)
            {
                log.Error(ex);
                return false;
            }
        }


        public Deal GetDealByNome(string nome)
        {
            return (from x in _entity.Deal.Include("Artigo")
                    where x.Descricao == nome
                    select x).SingleOrDefault();
        }


        public PagedList<UltimosViewModel> GetUltimos(int? id)
        {
            var result = from x in _entity.Deal.Include("Artigo")
                         where x.Favorito == false
                         orderby x.Data descending
                         select new UltimosViewModel {
                Nome = x.Texto,
                Descricao = x.Descricao,
                Data = x.Data,
                DealId = x.Id,
                DealLink ="",
                Disponivel = x.Disponivel,
                Image = x.Artigo.Imagem,
                Preco = x.PrecoDesconto,
                Valor = x.PrecoVenda,
                Poupa = x.PrecoVenda - x.PrecoDesconto,
                Comprados = x.TotalComprado,
                };

            return result.ToPagedList(id ?? 1, 10);
        }


        public SideDealViewModel GetSideDeal()
        {
            try
            {
                var deal = (from x in _entity.Deal.Include("Artigo")
                            where x.Disponivel == true
                            && x.SideDeal == true
                            select x).SingleOrDefault();

                if (deal == null) return null;

                return new SideDealViewModel
                {
                    Titulo = deal.Texto,
                    Imagem = deal.Artigo.Imagem,
                    IdDeal = deal.Id + "-" + deal.Descricao
                };
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                return null;
            }
        }

        public SideDealViewModel GetSideDeal(int id)
        {
            try
            {
                var deal = (from x in _entity.Deal.Include("Artigo")
                            where x.Disponivel == true
                            && x.Id == id
                            select x).SingleOrDefault();

                if (deal == null) return null;

                return new SideDealViewModel
                {
                    Titulo = deal.Texto,
                    Imagem = deal.Artigo.Imagem,
                    IdDeal = deal.Id + "-" + deal.Descricao
                };
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                return null;
            }
        }

        public DealViewModel GetDealDetalhe(int id)
        {
            var deal = GetDeal(id);

            return ReturnDealViewModel(deal);
        }

        private DealViewModel ReturnDealViewModel(Deal deal)
        {
            string percentagem = (1 - (deal.PrecoDesconto * 100 / deal.PrecoVenda) / 100).ToString("P0", CultureInfo.InvariantCulture);
            
            var parceiro = (from x in _entity.Parceiro.Include("GeoLocal")
                            where x.Id == deal.ParceiroId
                            select x).SingleOrDefault();
            
            List<GeoLocal> lstLocais = new List<GeoLocal>();

            foreach (var item in parceiro.GeoLocal)
            {
                lstLocais.Add(new GeoLocal { Latitude = item.Latitude, Longitude = item.Longitude });   
            }

            return new DealViewModel
            {
                Id = deal.Id,
                Desconto = percentagem,
                Descricao = deal.Descricao,
                Expira = deal.Expira,
                Imagem = deal.Artigo.Imagem,
                Poupa = String.Format("{0:F} €",deal.PrecoVenda - deal.PrecoDesconto),
                PrecoDesconto = String.Format("{0:F} €", deal.PrecoDesconto),
                PrecoVenda = String.Format("{0:F} €", deal.PrecoVenda),
                QtdMaxima = deal.QuantidadeMaxima,
                QtdMinima = deal.QuantidadeMinima,
                Texto = deal.Texto,
                TotalComprado = deal.TotalComprado,
                NomeParceiro = parceiro.NomeNegocio,
                GeoLocais = lstLocais,
                Condicoes = GetCondicoes(deal.Id),
                Destaques = GetDestaques(deal.Id),
                Apresentacao = parceiro.Apresentacao,
                Morada = parceiro.Morada,
                Localidade = parceiro.Localidade,
                CodPostal = parceiro.CodPostal,
                Telefone = parceiro.Telefone,
                Email = parceiro.Email,
                Disponivel = deal.QuantidadeMaxima <= deal.TotalComprado ? false : true,
                DealOn = deal.QuantidadeMinima <= deal.TotalComprado && deal.QuantidadeMaxima >= deal.TotalComprado ? true : false
            };
        }

        public ResultActualizar UpdateOrderDetailDeal(int id, int qtd)
        {
            var deal = GetDeal(id);

            return new ResultActualizar { 
            };
        }


        public string EnvioNewsletter(string email)
        {
            try
            {
                var tmp = _entity.EnvioNewsletter.Select(x => x.Email == email).FirstOrDefault();
                if (!tmp)
                { 
                    _entity.EnvioNewsletter.AddObject(new EnvioNewsletter { Email = email });
                    _entity.SaveChanges();
                    MailTools.Mail.SendSubscreveNewsletter(email);
                }
                return "OK";
            }
            catch(Exception ex)
            {
                log.Error(ex);
                return "Erro";
            }
        }


        public bool GravaDadosOferta(OrderDetailViewModel orderDetail)
        {
            try
            {
                DadosOferta res = new DadosOferta();

                res.EmailDest = orderDetail.EmailDest;
                res.EuImprimo = orderDetail.EuImprimo;
                res.Mensagem = orderDetail.Mensagem;
                res.NomeDe = orderDetail.NomeDe;
                res.NomePara = orderDetail.NomePara;


                HttpContext.Current.Session.Add("orderDetail+" +orderDetail.DealId.ToString(),res);

                return true;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                return false;
            }
        }


        public PagedList<FavoritosViewModel> GetFavoritos(int? id)
        {
            var result = from x in _entity.Deal.Include("Artigo")
                         where x.Disponivel == true 
                         && x.Favorito == true
                         orderby x.Data descending
                         select new FavoritosViewModel
                         {
                             Nome = x.Texto,
                             Descricao = x.Descricao,
                             Data = x.Data,
                             DealId = x.Id,
                             DealLink = "",
                             Disponivel = x.Disponivel,
                             Image = x.Artigo.Imagem,
                             Preco = x.PrecoDesconto,
                             Valor = x.PrecoVenda,
                             Poupa = x.PrecoVenda - x.PrecoDesconto,
                             Comprados = x.TotalComprado,
                         };

            return result.ToPagedList(id ?? 1, 10);
        }


        public bool ConcluiCompra(int idDeal, int quantidade =1)
        {
            try
            {
                var deal = GetDeal(idDeal);
                deal.TotalComprado += quantidade; 
                _entity.SaveChanges();

                ClienteRepository cli = new ClienteRepository();

                if (deal.TotalComprado >= deal.QuantidadeMinima)
                    return true;
                else
                    return false;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
                return false;
            }

        }


        public Deal GetDealByOrder(int orderId)
        {
            return (from o in _entity.Order
                      where o.Id == orderId
                      join od in _entity.OrderDetail on o.Id equals od.OrderId into g
                      from od in g
                      join d in _entity.Deal on od.DealId equals d.Id into q
                      from d in q
                      select d).SingleOrDefault();
        }


        public List<string> GetCondicoes(int idDeal)
        {
            Deal deal = GetDeal(idDeal);
            List<string> condicoes = new List<string>();
            foreach (var item in deal.Detalhe.Where(x => x.Tipo == "C"))
            {
                condicoes.Add(item.Texto);
            }

            return condicoes;
        }

        public List<string> GetDestaques(int idDeal)
        {
            Deal deal = GetDeal(idDeal);
            List<string> destaques = new List<string>();
            foreach (var item in deal.Detalhe.Where(x => x.Tipo == "D"))
            {
                destaques.Add(item.Texto);
            }
            return destaques;
        }
    }

    public class ResultActualizar
    {
        public decimal ValorUn { get; set; }
        public decimal Total { get; set; }
    }
}
